package com.xuzhiguang.lightnat.server.api.handler;

import com.xuzhiguang.lightnat.server.api.domain.ApiResponse;
import com.xuzhiguang.lightnat.server.api.domain.ResponseEnum;
import com.xuzhiguang.lightnat.server.core.exception.NatException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingRequestValueException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ValidationException;

@Slf4j
@ControllerAdvice
public class ApiExceptionHandler {

    /**
     * 自定义异常
     *
     * @param e
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(value = NatException.class)
    @ResponseBody
    public ApiResponse<Object> handle(NatException e, HttpServletRequest request, HttpServletResponse response) {
        return new ApiResponse<>(e.getCode(), e.getMessage(), null);
    }

    /**
     * 参数校验异常
     * @param e
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(value = MissingRequestValueException.class)
    @ResponseBody
    public ApiResponse<Object> handle(MissingRequestValueException e, HttpServletRequest request, HttpServletResponse response) {

        return new ApiResponse<>(ResponseEnum.PARAMETERS_VALIDATE_ERROR.getCode(),
                e.getMessage(), null);
    }

    /**
     * 参数校验异常
     * @param e
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ApiResponse<Object> handle(MethodArgumentNotValidException e, HttpServletRequest request, HttpServletResponse response) {

        String errorMsg;
        if (e.getBindingResult().hasFieldErrors()) {
            errorMsg = "parameter '" + e.getBindingResult().getFieldError().getField() + "' " + e.getBindingResult().getFieldError().getDefaultMessage();
        } else {
            errorMsg = ResponseEnum.PARAMETERS_VALIDATE_ERROR.getMsg();
        }

        return new ApiResponse<>(ResponseEnum.PARAMETERS_VALIDATE_ERROR.getCode(),
                errorMsg, null);
    }

    /**
     * 参数校验异常
     *
     * @param e
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(value = ValidationException.class)
    @ResponseBody
    public ApiResponse<Object> handle(ValidationException e, HttpServletRequest request, HttpServletResponse response) {

        return new ApiResponse<>(ResponseEnum.PARAMETERS_VALIDATE_ERROR.getCode(),
                e.getMessage(), null);
    }

    /**
     * json 格式化错误
     * @param e
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseBody
    public ApiResponse<Object> handle(HttpMessageNotReadableException e, HttpServletRequest request, HttpServletResponse response) {

        return new ApiResponse<>(ResponseEnum.PARAMETERS_VALIDATE_ERROR.getCode(),
                e.getMessage(), null);
    }

    /**
     * 未知异常
     *
     * @param e
     * @param request
     * @param response
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ApiResponse<Object> handle(Exception e, HttpServletRequest request, HttpServletResponse response) {
        log.error("system error", e);
        return new ApiResponse<>(ResponseEnum.SYSTEM_ERROR);
    }


}
